/**
 * @file MotorDriver.h
 * @author SoBigDog (623644973lubin@163.com)
 * @brief 
 * @version 0.1
 * @date 2020-09-27
 * 
 * @copyright Copyright (c) 2020
 * 
 */
#ifndef __MOTOR_DRIVER_H__
#define __MOTOR_DRIVER_H__

#include "stm32f1xx_hal.h"

const uint8_t ODO_STOP_TIME_WINDOW = 50;	// 50 * 10ms == 500ms
const uint8_t VEL_CACL_STOP_TIME_WINDOW = 20;
const uint8_t VEL_REC_STOP_TIME_WINDOW = 10;	
const uint8_t RX_MAILBOX_QUE_SIZE = 20;

class CDriverProtocol;



enum MotorType {
	MOTOR_TYPE_NULL = 0,
	MOTOR_TYPE_WALK,
	MOTOR_TYPE_STEER,
	MOTOR_TYPE_JACK,
	MOTOR_TYPE_SPIN,
	MOTOR_TYPE_LINEAR,
	MOTOR_TYPE_FORK,
	MOTOR_TYPE_STEER_WALK_FORK
};

enum motorLimitFlag {
	Limit_NONE = 0,
	Limit_UP,
	Limit_DOWN,
	Limit_ERR,
};
//添加新的电机必须顺延下去，不能插队
class CMotorDriverBase {
public:
	enum MotorCalibMethod {
		MOTOR_CALIB_NULL = 0,
		MOTOR_CALIB_BY_DRIVER,
		MOTOR_CALIB_BY_VELOCITY
	};
	CMotorDriverBase();
	virtual ~CMotorDriverBase();
	bool read();
	bool readOperational();
	virtual int init();
	virtual void doCalibration();
	virtual void sendCalibCheck();
	virtual void sendZeroVel();
	virtual void sendCtrlVel(float s);	// cnt/s
	virtual void sendTargetPos(int32_t);
	virtual void sendTargetPosOK(int32_t s);
	virtual void sendPosReq();
	virtual void sendStatusReq();
	virtual void sendEnable();
	virtual void sendDisable();
	virtual void checkConnect();
	virtual void clearErrorcode();
	float position(); 					// m
	float velocity();
	void driverLifeGuard();
	bool encodeTimeout();
	int32_t inverse(){return _inverse;}
	CDriverProtocol* Protocol() const {
		return _driverProtocol;
	}

	/* 重写 */
	
//	virtual bool timeout() 
//	{
//		int32_t now_time = BaseTimer::Instance()->getTime();
//		int32_t diff = now_time - _response_time;
//		if ( diff < 0 ) {
//			diff &= 0x7FFFFFFF;
//		}
//		
//		if (diff >= 120) {
//			_isConnected = false;
//			_is_odo_update_after_connect = false;
//			_after_offset_flag = false;
//			_canBaseRouter->setAutoTransmit(false);
//			return true;
//		} else {
//			return false;
//		}
//	}
	
	virtual bool connected(){return _isConnected;}

	float scale(){return _scale;}
	bool isStopped(){return _is_stopped && !_is_moving;}
	void moveMonitor();
	MotorType motorType(){return _motorType;}
	float isUpdated(){
		return _is_updated;
	}
	void resetUpdated(){
		_is_updated = false;
	}
	void resetAfterConnected();
	bool isWaitProcessConnect(){return _is_wait_process_connect;}
	virtual void maualCalib(/*uint8_t method*/){return;}
protected:
	char _protocol[30];
	char _outEncoderBrand[30];
	MotorType _motorType;
	CDriverProtocol* _driverProtocol;
	int32_t _response_time;
	int32_t _motorspeed;
	uint64_t _encoder_timestamp_nsec_;
	uint64_t _pre_timestamp_nsec_;
	int _cur_ret_msg_num;
	int _total_ret_msg_num;
	bool _isConnected;
	bool _is_wait_process_connect;
	bool _is_NMT_process_connect;
	bool _is_wait_process_start;
	
	float _scale;
	int32_t _inverse;
	bool _is_stopped;
	bool _is_moving;
	bool _is_updated;
	int32_t _last_cnt;
	uint8_t _odo_time_window_counter;
	bool _first_in;
	int _stop_cycle;
	float _critical_delta;
	float _critical_window_delta;
	float _lastRecvCmd;
	uint8_t _forwardState;
	enum motorLimitFlag _motor_limit;
	bool _is_odo_update_after_connect;
	float _offset;
	
};

#endif	// ~__MOTOR_DRIVER_H__
